using Game.Networking.Utils;
using TMPro;
using UnityEngine.UI;
using UnityEngine;

namespace Game.UI {
	public class CodeEditorWindow : UIWindow {
		public TMP_Text   Header;
		public InGameTextEditor.TextEditor CodeEditor;

		public Button SaveButton;

		string _selectedFileName;
		IComputingUnitUserDataProvider _dataProvider;

		protected override void Awake() {
			base.Awake();
			var isServer = NetworkOptions.StartServer;
			if ( isServer ) {
				_dataProvider = new ServerComputingUnitUserDataProvider();
			} else {
				_dataProvider = new ClientComputingUnitUserDataProvider();
			}

			SaveButton.onClick.AddListener(OnSaveButtonClick);
			CodeEditor.deactivateOnClickOutsideOfEditor = true;
		}

		private void Start() {
			_dataProvider?.OnCodeFileUpdated?.Subscribe(this, OnCodeFileUpdated);
			_dataProvider?.OnCodeFileListUpdated?.Subscribe(this, OnCodeFileListUpdated);
		}

		private void Update() {
			if ( CodeEditor.EditorActive ) {
				if ( Input.GetKey(KeyCode.LeftControl) ) {
					if ( Input.GetKeyDown(KeyCode.S) ) {
						OnSaveButtonClick();
					}
					if ( Input.GetKeyUp(KeyCode.W) ) {
						HideWindow();
					}
				}
			}
		}

		public void ShowWindow(string fileName, string contents) {
			_selectedFileName = fileName;
			CodeEditor.ClearHistory();
			CodeEditor.SetText(contents, true);
			ShowWindow();
			Header.text = $"Code Editor: {fileName}";
		}

		void OnSaveButtonClick() {
			_dataProvider.SaveCodeFile(_selectedFileName, CodeEditor.Text);
		}

		void OnCodeFileUpdated(string fileName) {
			if ( _selectedFileName != fileName ) {
				return;
			}
			CodeEditor.ClearHistory();
			CodeEditor.SetText(_dataProvider.GetFileContents(fileName), true);
		}

		void OnCodeFileListUpdated() {
			var files = _dataProvider.GetCodeFiles();
			if ( gameObject.activeInHierarchy && !files.Contains(_selectedFileName) ) {
				HideWindow();
			}
		}

		public override void HideWindow() {
			if ( !string.IsNullOrEmpty(_selectedFileName) ) {
				_dataProvider?.SaveCodeFileLocally(_selectedFileName, CodeEditor.Text);
			}
			
			base.HideWindow();

		}

		public override void OnWindowShow() {
			base.OnWindowShow();
			CodeEditor.EditorActive = true;
		}
	}
}
